﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime;
using System.Runtime.InteropServices;

namespace PENet
{
    public class PEStructures
    {
        #region ENUMS

        public enum IMAGE_DIRECTORY_TYPES_ENUM
        {
            IMAGE_DIRECTORY_ENTRY_EXPORT = 0,           // Export Directory +
            IMAGE_DIRECTORY_ENTRY_IMPORT = 1,           // Import Directory +
            IMAGE_DIRECTORY_ENTRY_RESOURCE = 2,         // Resource Directory +
            IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3,        // Exception Directory +
            IMAGE_DIRECTORY_ENTRY_SECURITY = 4,         // Security Directory -
            IMAGE_DIRECTORY_ENTRY_BASERELOC = 5,        // Base Relocation Table +
            IMAGE_DIRECTORY_ENTRY_DEBUG = 6,            // Debug Directory +
            IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7,     // Architecture Specific Data -
            IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8,        // RVA of GP -
            IMAGE_DIRECTORY_ENTRY_TLS = 9,              // TLS Directory +
            IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10,      // Load Configuration Directory +
            IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11,     // Bound Import Directory in headers -
            IMAGE_DIRECTORY_ENTRY_IAT = 12,              // Import Address Table -
            IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13,     // Delay Load Import Descriptors -
            IMAGE_DIRECTORY_ENTRY_COM_CLR_DESCRIPTOR = 14   // COM Runtime descriptor +
        };

        public enum IMAGE_MACHINE_TYPES_ENUM
        {
            IMAGE_FILE_MACHINE_UNKNOWN = 0,
            IMAGE_FILE_MACHINE_I386 = 0x014c,  // Intel 386.
            IMAGE_FILE_MACHINE_R3000 = 0x0162,  // MIPS little-endian, 0x160 big-endian
            IMAGE_FILE_MACHINE_R4000 = 0x0166,  // MIPS little-endian
            IMAGE_FILE_MACHINE_R10000 = 0x0168,  // MIPS little-endian
            IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x0169,  // MIPS little-endian WCE v2
            IMAGE_FILE_MACHINE_ALPHA = 0x0184,  // Alpha_AXP
            IMAGE_FILE_MACHINE_SH3 = 0x01a2,  // SH3 little-endian
            IMAGE_FILE_MACHINE_SH3DSP = 0x01a3,
            IMAGE_FILE_MACHINE_SH3E = 0x01a4,  // SH3E little-endian
            IMAGE_FILE_MACHINE_SH4 = 0x01a6,  // SH4 little-endian
            IMAGE_FILE_MACHINE_SH5 = 0x01a8,  // SH5
            IMAGE_FILE_MACHINE_ARM = 0x01c0,  // ARM Little-Endian
            IMAGE_FILE_MACHINE_THUMB = 0x01c2,  // ARM Thumb/Thumb-2 Little-Endian
            IMAGE_FILE_MACHINE_ARMNT = 0x01c4,  // ARM Thumb-2 Little-Endian
            IMAGE_FILE_MACHINE_AM33 = 0x01d3,
            IMAGE_FILE_MACHINE_POWERPC = 0x01F0,  // IBM PowerPC Little-Endian
            IMAGE_FILE_MACHINE_POWERPCFP = 0x01f1,
            IMAGE_FILE_MACHINE_IA64 = 0x0200,  // Intel 64
            IMAGE_FILE_MACHINE_MIPS16 = 0x0266,  // MIPS
            IMAGE_FILE_MACHINE_ALPHA64 = 0x0284,  // ALPHA64
            IMAGE_FILE_MACHINE_MIPSFPU = 0x0366,  // MIPS
            IMAGE_FILE_MACHINE_MIPSFPU16 = 0x0466,  // MIPS
            IMAGE_FILE_MACHINE_TRICORE = 0x0520,  // Infineon
            IMAGE_FILE_MACHINE_CEF = 0x0CEF,
            IMAGE_FILE_MACHINE_EBC = 0x0EBC,  // EFI Byte Code
            IMAGE_FILE_MACHINE_AMD64 = 0x8664,  // AMD64 (K8)
            IMAGE_FILE_MACHINE_M32R = 0x9041,  // M32R little-endian
            IMAGE_FILE_MACHINE_CEE = 0xC0EE,
        };

        #endregion

        #region STRUCTURES

        [StructLayout(LayoutKind.Explicit, Size = 64)]
        public struct IMAGE_DOS_HEADER
        {      // DOS .EXE header
            [FieldOffsetAttribute(0)]
            public UInt16 e_magic;                     // Magic number
            [FieldOffsetAttribute(2)]
            public UInt16 e_cblp;                      // Bytes on last page of file
            [FieldOffsetAttribute(4)]
            public UInt16 e_cp;                        // Pages in file
            [FieldOffsetAttribute(6)]
            public UInt16 e_crlc;                      // Relocations
            [FieldOffsetAttribute(8)]
            public UInt16 e_cparhdr;                   // Size of header in paragraphs
            [FieldOffsetAttribute(10)]
            public UInt16 e_minalloc;                  // Minimum extra paragraphs needed
            [FieldOffsetAttribute(12)]
            public UInt16 e_maxalloc;                  // Maximum extra paragraphs needed
            [FieldOffsetAttribute(14)]
            public UInt16 e_ss;                        // Initial (relative) SS value
            [FieldOffsetAttribute(16)]
            public UInt16 e_sp;                        // Initial SP value
            [FieldOffsetAttribute(18)]
            public UInt16 e_csum;                      // Checksum
            [FieldOffsetAttribute(20)]
            public UInt16 e_ip;                        // Initial IP value
            [FieldOffsetAttribute(22)]
            public UInt16 e_cs;                        // Initial (relative) CS value
            [FieldOffsetAttribute(24)]
            public UInt16 e_lfarlc;                    // File address of relocation table
            [FieldOffsetAttribute(26)]
            public UInt16 e_ovno;                      // Overlay number
            [FieldOffsetAttribute(28)]
            public UInt16[] e_res;                    // 4 WORD Reserved UInt16s
            [FieldOffsetAttribute(36)]
            public UInt16 e_oemid;                     // OEM identifier (for e_oeminfo)
            [FieldOffsetAttribute(38)]
            public UInt16 e_oeminfo;                   // OEM information; e_oemid specific
            [FieldOffsetAttribute(40)]
            public UInt16[] e_res2;                    // 10 WORD Reserved UInt16s
            [FieldOffsetAttribute(60)]
            public UInt32 e_lfanew;                    // File address of new exe header
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 20)]
        public struct IMAGE_FILE_HEADER
        {
            [FieldOffsetAttribute(0)]
            public UInt16 Machine;
            [FieldOffsetAttribute(2)]
            public UInt16 NumberOfSections;
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(8)]
            public UInt32 PointerToSymbolTable;
            [FieldOffsetAttribute(12)]
            public UInt32 NumberOfSymbols;
            [FieldOffsetAttribute(16)]
            public UInt16 SizeOfOptionalHeader;
            [FieldOffsetAttribute(18)]
            public UInt16 Characteristics;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 8)]
        public struct IMAGE_DATA_DIRECTORY
        {
            [FieldOffsetAttribute(0)]
            public UInt32 VirtualAddress;
            [FieldOffsetAttribute(4)]
            public UInt32 Size;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 224)]
        public struct IMAGE_OPTIONAL_HEADER
        {
            [FieldOffsetAttribute(0)]
            public UInt16 Magic;
            [FieldOffsetAttribute(2)]
            public char MajorLinkerVersion;
            [FieldOffsetAttribute(3)]
            public char MinorLinkerVersion;
            [FieldOffsetAttribute(4)]
            public UInt32 SizeOfCode;
            [FieldOffsetAttribute(8)]
            public UInt32 SizeOfInitializedData;
            [FieldOffsetAttribute(12)]
            public UInt32 SizeOfUninitializedData;
            [FieldOffsetAttribute(16)]
            public UInt32 AddressOfEntryPoint;
            [FieldOffsetAttribute(20)]
            public UInt32 BaseOfCode;
            [FieldOffsetAttribute(24)]
            public UInt32 BaseOfData;
            [FieldOffsetAttribute(28)]
            public UInt32 ImageBase;
            [FieldOffsetAttribute(32)]
            public UInt32 SectionAlignment;
            [FieldOffsetAttribute(36)]
            public UInt32 FileAlignment;
            [FieldOffsetAttribute(40)]
            public UInt16 MajorOperatingSystemVersion;
            [FieldOffsetAttribute(42)]
            public UInt16 MinorOperatingSystemVersion;
            [FieldOffsetAttribute(44)]
            public UInt16 MajorImageVersion;
            [FieldOffsetAttribute(46)]
            public UInt16 MinorImageVersion;
            [FieldOffsetAttribute(48)]
            public UInt16 MajorSubsystemVersion;
            [FieldOffsetAttribute(50)]
            public UInt16 MinorSubsystemVersion;
            [FieldOffsetAttribute(52)]
            public UInt32 Win32VersionValue;
            [FieldOffsetAttribute(56)]
            public UInt32 SizeOfImage;
            [FieldOffsetAttribute(60)]
            public UInt32 SizeOfHeaders;
            [FieldOffsetAttribute(64)]
            public UInt32 CheckSum;
            [FieldOffsetAttribute(68)]
            public UInt16 Subsystem;
            [FieldOffsetAttribute(70)]
            public UInt16 DllCharacteristics;
            [FieldOffsetAttribute(72)]
            public UInt32 SizeOfStackReserve;
            [FieldOffsetAttribute(76)]
            public UInt32 SizeOfStackCommit;
            [FieldOffsetAttribute(80)]
            public UInt32 SizeOfHeapReserve;
            [FieldOffsetAttribute(84)]
            public UInt32 SizeOfHeapCommit;
            [FieldOffsetAttribute(88)]
            public UInt32 LoaderFlags;
            [FieldOffsetAttribute(92)]
            public UInt32 NumberOfRvaAndSizes;
            [FieldOffsetAttribute(96)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public IMAGE_DATA_DIRECTORY[] DataDirectory;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 248)]
        public struct IMAGE_NT_HEADERS
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Signature;
            [FieldOffsetAttribute(4)]
            public IMAGE_FILE_HEADER FileHeader;
            [FieldOffsetAttribute(24)]
            public IMAGE_OPTIONAL_HEADER OptionalHeader;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 40)]
        public struct IMAGE_SECTION_HEADER_RECORD
        {
            [FieldOffsetAttribute(0)]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public char[] Name;
            [FieldOffsetAttribute(8)]
            public UInt32 PhysicalAddress;
            [FieldOffsetAttribute(8)]
            public UInt32 VirtualSize;
            [FieldOffsetAttribute(12)]
            public UInt32 VirtualAddress;
            [FieldOffsetAttribute(16)]
            public UInt32 SizeOfRawData;
            [FieldOffsetAttribute(20)]
            public UInt32 PointerToRawData;
            [FieldOffsetAttribute(24)]
            public UInt32 PointerToRelocations;
            [FieldOffsetAttribute(28)]
            public UInt32 PointerToLinenumbers;
            [FieldOffsetAttribute(32)]
            public UInt16 NumberOfRelocations;
            [FieldOffsetAttribute(34)]
            public UInt16 NumberOfLinenumbers;
            [FieldOffsetAttribute(36)]
            public UInt32 Characteristics;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 28)]
        public struct IMAGE_DEBUG_DIRECTORY
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Characteristics;
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(8)]
            public UInt16 MajorVersion;
            [FieldOffsetAttribute(10)]
            public UInt16 MinorVersion;
            [FieldOffsetAttribute(12)]
            public UInt32 Type;
            [FieldOffsetAttribute(16)]
            public UInt32 SizeOfData;
            [FieldOffsetAttribute(20)]
            public UInt32 AddressOfRawData;
            [FieldOffsetAttribute(24)]
            public UInt32 PointerToRawData;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 40)]
        public struct IMAGE_EXPORT_DIRECTORY_TABLE
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Characteristics;
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(8)]
            public UInt16 MajorVersion;
            [FieldOffsetAttribute(10)]
            public UInt16 MinorVersion;
            [FieldOffsetAttribute(12)]
            public UInt32 Name;
            [FieldOffsetAttribute(16)]
            public UInt32 Base;
            [FieldOffsetAttribute(20)]
            public UInt32 NumberOfFunctions;
            [FieldOffsetAttribute(24)]
            public UInt32 NumberOfNames;
            [FieldOffsetAttribute(28)]
            public UInt32 AddressOfFunctions;     // RVA from base of image
            [FieldOffsetAttribute(32)]
            public UInt32 AddressOfNames;         // RVA from base of image
            [FieldOffsetAttribute(36)]
            public UInt32 AddressOfNameOrdinals;  // RVA from base of image
        }

        [StructLayout(LayoutKind.Explicit, Size = 4)]
        public struct IMAGE_EXPORT_ADDRESS_TABLE
        {
            [FieldOffsetAttribute(0)]
            public UInt32 ExportRVA;
            [FieldOffsetAttribute(0)]
            public UInt32 ForwarderRVA;
        }

        public struct IMAGE_EXPORT_DIRECTORY
        {
            public IMAGE_EXPORT_DIRECTORY_TABLE ExportDirectoryTable;
            public IMAGE_EXPORT_ADDRESS_TABLE[] ExportAddressTable;
            public UInt32[] ExportNamePointerTable;
            public UInt16[] ExportOrdinalTable;
            public String[] ExportNameTable;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 20)]
        public struct IMAGE_IMPORT_DESCRIPTOR
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Characteristics;      // 0 for terminating null import descriptor
            [FieldOffsetAttribute(0)]
            public UInt32 OriginalFirstThunk;   // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;        // 0 if not bound,
            // -1 if bound, and real date\time stamp
            //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
            // O.W. date/time stamp of DLL bound to (Old BIND)
            [FieldOffsetAttribute(8)]
            public UInt32 ForwarderChain;       // -1 if no forwarders
            [FieldOffsetAttribute(12)]
            public UInt32 Name;
            [FieldOffsetAttribute(16)]
            public UInt32 FirstThunk;           // RVA to IAT (if bound this IAT has actual addresses)
        }

        public struct IMAGE_IMPORT_HINT_NAME
        {
            public UInt16 Hint;
            public String Name;
        }

        public struct IMAGE_IMPORT_DIRECTORY_RECORD
        {
            public IMAGE_IMPORT_DESCRIPTOR ImportDescriptor;
            public String Name;
            public UInt32[] ImportLookupTable;
            public UInt16[] ImportByOrdinalTable;
            public IMAGE_IMPORT_HINT_NAME[] ImportByNameTable;
        }

        public struct IMAGE_IMPORT_DIRECTORY
        {
            public IMAGE_IMPORT_DIRECTORY_RECORD[] ImportDirectories;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 20)]
        public class IMAGE_EXCEPTION_X86
        {
            [FieldOffsetAttribute(0)]
            public UInt32 BeginAddress;
            [FieldOffsetAttribute(4)]
            public UInt32 EndAddress;
            [FieldOffsetAttribute(8)]
            public UInt32 ExceptionHandler;
            [FieldOffsetAttribute(12)]
            public UInt32 HandlerData;
            [FieldOffsetAttribute(16)]
            public UInt32 PrologEndAddress;
        }

        public class IMAGE_EXCEPTION
        {
            public Boolean Is32Bit;
            public IMAGE_EXCEPTION_X86[] Exception_32Bit;
        }

        //*********************************************************************************//
        public struct IMAGE_RELOCATION_ENTRY
        {
            public UInt32 PageRVA;
            public UInt32 BlockSize;
            public UInt16[] Types;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 24)]
        public struct IMAGE_TLS_DIRECTORY_HEADER32
        {
            [FieldOffsetAttribute(0)]
            public UInt32 StartAddressOfRawData;
            [FieldOffsetAttribute(4)]
            public UInt32 EndAddressOfRawData;
            [FieldOffsetAttribute(8)]
            public UInt32 AddressOfIndex;             // PDWORD
            [FieldOffsetAttribute(12)]
            public UInt32 AddressOfCallBacks;         // PIMAGE_TLS_CALLBACK *
            [FieldOffsetAttribute(16)]
            public UInt32 SizeOfZeroFill;
            [FieldOffsetAttribute(20)]
            public UInt32 Characteristics;
        }

        public struct IMAGE_TLS_DIRECTORY
        {
            public Boolean Is32Bit;
            public IMAGE_TLS_DIRECTORY_HEADER32 Header;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 92)]
        public struct IMAGE_LOAD_CONFIG_DIRECTORY32
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Size;
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(8)]
            public UInt16 MajorVersion;
            [FieldOffsetAttribute(10)]
            public UInt16 MinorVersion;
            [FieldOffsetAttribute(12)]
            public UInt32 GlobalFlagsClear;
            [FieldOffsetAttribute(16)]
            public UInt32 GlobalFlagsSet;
            [FieldOffsetAttribute(20)]
            public UInt32 CriticalSectionDefaultTimeout;
            [FieldOffsetAttribute(24)]
            public UInt32 DeCommitFreeBlockThreshold;
            [FieldOffsetAttribute(28)]
            public UInt32 DeCommitTotalFreeThreshold;
            [FieldOffsetAttribute(32)]
            public UInt32 LockPrefixTable;                // VA
            [FieldOffsetAttribute(36)]
            public UInt32 MaximumAllocationSize;
            [FieldOffsetAttribute(40)]
            public UInt32 VirtualMemoryThreshold;
            [FieldOffsetAttribute(44)]
            public UInt32 ProcessHeapFlags;
            [FieldOffsetAttribute(48)]
            public UInt32 ProcessAffinityMask;
            [FieldOffsetAttribute(52)]
            public UInt16 CSDVersion;
            [FieldOffsetAttribute(54)]
            public UInt16 Reserved1;
            [FieldOffsetAttribute(56)]
            public UInt32 EditList;                       // VA
            [FieldOffsetAttribute(60)]
            public UInt32 SecurityCookie;                 // VA
            [FieldOffsetAttribute(64)]
            public UInt32 SEHandlerTable;                 // VA
            [FieldOffsetAttribute(68)]
            public UInt32 SEHandlerCount;
            [FieldOffsetAttribute(72)]
            public UInt32 GuardCFCheckFunctionPointer;    // VA
            [FieldOffsetAttribute(76)]
            public UInt32 Reserved2;
            [FieldOffsetAttribute(80)]
            public UInt32 GuardCFFunctionTable;           // VA
            [FieldOffsetAttribute(84)]
            public UInt32 GuardCFFunctionCount;
            [FieldOffsetAttribute(88)]
            public UInt32 GuardFlags;
        }

        public struct IMAGE_LOAD_CONFIG_DIRECTORY
        {
            public Boolean Is32Bit;
            public IMAGE_LOAD_CONFIG_DIRECTORY32 LoadConfig_32Bit;
        }

        //*********************************************************************************//
        [StructLayout(LayoutKind.Explicit, Size = 72)]
        public struct IMAGE_COR20_HEADER
        {
            // Header versioning
            [FieldOffsetAttribute(0)]
            public UInt32 cb;
            [FieldOffsetAttribute(4)]
            public UInt16 MajorRuntimeVersion;
            [FieldOffsetAttribute(6)]
            public UInt16 MinorRuntimeVersion;

            // Symbol table and startup information
            [FieldOffsetAttribute(8)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY MetaData;
            [FieldOffsetAttribute(16)]
            public UInt32 Flags;

            // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is not set, EntryPointToken represents a managed entrypoint.
            // If COMIMAGE_FLAGS_NATIVE_ENTRYPOINT is set, EntryPointRVA represents an RVA to a native entrypoint.
            [FieldOffsetAttribute(20)]
            public UInt32 EntryPointToken;
            [FieldOffsetAttribute(20)]
            public UInt32 EntryPointRVA;

            // Binding information
            [FieldOffsetAttribute(24)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY Resources;
            [FieldOffsetAttribute(32)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY StrongNameSignature;

            // Regular fixup and binding information
            [FieldOffsetAttribute(40)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY CodeManagerTable;
            [FieldOffsetAttribute(48)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY VTableFixups;
            [FieldOffsetAttribute(56)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY ExportAddressTableJumps;

            // Precompiled image info (internal use only - set to zero)
            [FieldOffsetAttribute(64)]
            [MarshalAs(UnmanagedType.Struct)]
            public IMAGE_DATA_DIRECTORY ManagedNativeHeader;
        }

        public struct IMAGE_CLR
        {
            public IMAGE_COR20_HEADER Core20Header;
        }

        //*********************************************************************************//
        public enum ResourceNodeType{
            ResourceDirectoryTable,
            ResourceDirectoryEntry,
            ResourceDataEntry,
        };

        [StructLayout(LayoutKind.Explicit, Size = 16)]
        public struct IMAGE_RESOURCE_DIRECTORY_TABLE
        {
            [FieldOffsetAttribute(0)]
            public UInt32 Characteristics;
            [FieldOffsetAttribute(4)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(8)]
            public UInt16 MajorVersion;
            [FieldOffsetAttribute(10)]
            public UInt16 MinorVersion;
            [FieldOffsetAttribute(12)]
            public UInt16 NumberOfNamedEntries;
            [FieldOffsetAttribute(14)]
            public UInt16 NumberOfIdEntries;
        }

        [StructLayout(LayoutKind.Explicit, Size = 8)]
        public struct IMAGE_RESOURCE_DIRECTORY_TABLE_ENTRY_INTERNAL
        {
            [FieldOffsetAttribute(0)]
            public UInt32 NameRVA;
            [FieldOffsetAttribute(0)]
            public UInt32 IntegerID;
            [FieldOffsetAttribute(4)]
            public UInt32 DataEntryRVA;
            [FieldOffsetAttribute(4)]
            public UInt32 SubdirectoryRVA;
        }

        public struct IMAGE_RESOURCE_DIRECTORY_TABLE_ENTRY
        {
            public Boolean IsNamed;
            public Boolean HasDataEntry;
            public UInt32 NameRVA;
            public UInt32 IntegerID;
            public String Name;
            public UInt32 SubDirectoryOrDataEntryRVA;
        }

        [StructLayout(LayoutKind.Explicit, Size = 16)]
        public struct IMAGE_RESOURCE_DATA_ENTRY
        {
            [FieldOffsetAttribute(0)]
            public UInt32 OffsetToData;
            [FieldOffsetAttribute(4)]
            public UInt32 Size;
            [FieldOffsetAttribute(8)]
            public UInt32 CodePage;
            [FieldOffsetAttribute(12)]
            public UInt32 Reserved;
        }
        public struct IMAGE_RESOURCE_DATA
        {
            public IMAGE_RESOURCE_DATA_ENTRY DataEntry;
            public Byte[] Data;
        }

        public struct IMAGE_RESOURCE_DIRECTORY_STRING
        {
            public UInt16 Length;
            public char[] NameString;
        }

        public struct IMAGE_RESOURCE_DIRECTORY
        {
            public ResourceNodeType NodeType;
            
            // in case the NodeType==ImageResourceDirectory
            public IMAGE_RESOURCE_DIRECTORY_TABLE ResourceDirectoryTable;

            // in case the NodeType==ImageTableEntry
            public IMAGE_RESOURCE_DIRECTORY_TABLE_ENTRY TableEntry;

            // in case the NodeType==ImageResourceData
            public IMAGE_RESOURCE_DATA ResourceData;

            public IMAGE_RESOURCE_DIRECTORY[] NextLevelNodes;
        }
        //*********************************************************************************//

        [StructLayout(LayoutKind.Explicit, Size = 8)]
        public struct IMAGE_BOUND_IMPORT_DESCRIPTOR
        {
            [FieldOffsetAttribute(0)]
            public UInt32 TimeDateStamp;
            [FieldOffsetAttribute(4)]
            public UInt16 OffsetModuleName;
            [FieldOffsetAttribute(6)]
            public UInt16 NumberOfModuleForwarderRefs;
            // Array of zero or more IMAGE_BOUND_FORWARDER_REF follows
        }
        
        //*********************************************************************************//

        #endregion
    }
}
